import os
import fmt
import path
import syscall
import parker.log as * 
import parker.util
import compress.tgz

var version = '0.1.0'

if util.arg_version() {
    fmt.printf('version: %v\n', version)
    return
}

if util.arg_verbose() {
    tgz.verbose = true
    set_verbose()
}

var args = os.args()

// - 读取当前程序所在目录，找到 runner 程序
assertf(args.len > 1, 'args failed')

// 可能是一个绝对路径也可以是一个相对 path
var exec_path = os.exe()
logf('exec_path: %v', exec_path)

var target_name = args[1]

// - 读取当前工作目录, 确定需要打包的目录
var workdir = syscall.getcwd()
logf('workdir: %v, target: %v', workdir, target_name)
var target_path = path.join(workdir, target_name)
// - 检查文件是否存在
assertf(path.exists(target_path), 'file=%v notfound', target_path)
logf('target_path: %v found', target_path)

workdir = path.dir(target_path)
target_name = path.base(target_path)

logf('new split workdir: %v, target: %v', workdir, target_name)

// .target_name 将 target_name 写入到文件 .target_name 中随压缩包一起压缩
var target_name_fd = syscall.open('.target_name', syscall.O_RDWR | syscall.O_CREAT, 0755)
syscall.write(target_name_fd, target_name as [u8])
syscall.close(target_name_fd)

// - 压缩到工作目录即可, 名字就叫 {target_name}.tar.gz
var tgz_name = fmt.sprintf('%v.tar.gz', target_name)

// new target_name + 'd' fd, node -> noded
var output_name = fmt.sprintf('%v-c', target_name)

// - 遍历当前工作目录中的所有文件，进行压缩
var sources = os.listdir(workdir)
[string] temp = []
for s in sources {
    if {tgz_name, output_name}.contains(s) {
        logf('tgz encode source %v will continue', s)
        continue
    }

    temp.push(s)
}
sources = temp

tgz.encode(workdir, tgz_name, sources)

logf('encode to tgz_name %v in %v', tgz_name, workdir)


// 如果存在环境变量 RUNNER_PATH, 则有优先读取环境变量
var runner_path =  syscall.get_env('RUNNER_PATH')
if runner_path == '' {
    var parker_dir = path.dir(exec_path)
    runner_path = path.join(parker_dir, 'runner')
}

assertf(path.exists(runner_path), 'runner file=%v notfound', runner_path)
logf('runner_path=%v found', runner_path)

// open and create
var output_fd = syscall.open(output_name, syscall.O_CREAT | syscall.O_RDWR | syscall.O_TRUNC, 0755)

// - append runner
var runner_fd = syscall.open(runner_path, syscall.O_RDONLY, 0666)

// 通用读取和写入 buf
var buf = vec<u8>{len=102400}
var readsum = 0

for true {
    var len = syscall.read(runner_fd, buf)
    readsum += len
    if len == 0 {
        break
    }

    syscall.write(output_fd, buf.ref(), len)
    // logf('read item len: %v and write to output file', len)
}
syscall.close(runner_fd)
logf('write runner to output success, size=%v', readsum)

// - append tgz
var tgz_fd = syscall.open(tgz_name, syscall.O_RDONLY, 0666)
readsum = 0

for true {
    var len = syscall.read(tgz_fd, buf)
    readsum += len
    if len == 0 {
        break
    }

    syscall.write(output_fd, buf.ref(), len)
}
syscall.close(tgz_fd)
os.remove(tgz_name)
os.remove('.target_name')
logf('append tgz to output success, and remove tgz/.target_name success, size=%v', readsum)


var tgz_size = readsum
logf('stat tgz %v get size=%d', tgz_name, tgz_size)

var tgz_size_str = fmt.sprintf('%016d', tgz_size)
syscall.write(output_fd, tgz_size_str as [u8])
logf('tag_size to output success, size_str=%v', tgz_size_str)

logf('runner %s make successful', path.join(workdir, output_name))

// - 信息输出
fmt.printf('%s\n', output_name)
for i, item in sources {
    if item == '.target_name' {
        continue
    }

    if i < sources.len - 1 {
        fmt.printf('├── %s\n', item)
    } else {
        fmt.printf('└── %s\n', item)
    }
}
fmt.printf('🍻 parker successful\n')
